package com.asa.base

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.LayoutRes
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider

abstract class BaseFragment<B:ViewDataBinding,VM:BaseViewModel>:Fragment() {

    protected lateinit var binding : B
        private set

    protected lateinit var viewModel:VM
        private set

    /**
     * 是否已经加载过数据
     */
    private var hasLoadData = false

    /**
     * 视图是否已经加载完毕
     */
    private var isViewPrepare = false

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        injectViewBinding(inflater,container)
        injectViewModel()
        return binding.root
    }

    private fun injectViewBinding(inflater: LayoutInflater,container: ViewGroup?){
        binding = DataBindingUtil.inflate(inflater,getLayoutId(),container,false)
        binding.lifecycleOwner = this
    }

    private fun injectViewModel() {
        val vm = createModel()
        viewModel = ViewModelProvider(this,BaseViewModel.createViewModelFactory(vm)).get(vm::class.java)
    }

    abstract fun createModel(): VM
    @LayoutRes
    protected abstract fun getLayoutId():Int


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        isViewPrepare = true
        initView()
        lazyLoadDataIfPrepare()
    }

    override fun setUserVisibleHint(isVisibleToUser: Boolean) {
        super.setUserVisibleHint(isVisibleToUser)
        if (isVisibleToUser){
            lazyLoadDataIfPrepare()
        }
    }
    private fun lazyLoadDataIfPrepare() {
        if (userVisibleHint &&  isViewPrepare && !hasLoadData){
            lazyLoad()
            hasLoadData = true
        }
    }

    abstract fun lazyLoad()

    abstract fun initView()

}